package com.nereyda.application
{
	import com.nereyda.controller.MappingController;
	import com.nereyda.responses.*;
	import org.moyrax.nereyda.services.core.*;
	import org.moyrax.nereyda.services.events.*;
	import org.moyrax.nereyda.services.factory.JROIMContentFactory;
	
	import flash.net.FileReference;
	
	import mx.controls.Alert;
	import mx.core.IFlexDisplayObject;
	import mx.core.UIComponent;
	import mx.managers.CursorManager;
	import mx.managers.PopUpManager;
	//
	/**
	 * JSON Remote Object Invokation Model
	 */
	public class Globals
	{
		public const REMOTE_HOST :String = "index.php";
		public const appTitle :String = "WDesk";

		// Configuración de conexión con el servidor.
		//
		[Bindable]
		public var configure :Configure = new Configure();
		
		[Bindable]
		public var contentFactory :JROIMContentFactory = new JROIMContentFactory();

		[Bindable]
		public var currentStyleScheme :String = "current";

		[Bindable]
		public var loading :Boolean = true;
		
		/**
		 * Esta función resume la llamada a un servicio web, permitiendo
		 * especificar todos los datos de la petición sin tener que crear
		 * los objetos correspondientes.
		 * 
		 * @param serviceName  Nombre del servicio web al que se llamará.
		 * @param endpointName Nombre del endpoint que se ejecutará en el servicio.
		 * @param params       Parámetros que se le pasarán a la función del endpoint.
		 * @param event        Evento que se desencadenará al recibir la respuesta.
		 * @param eventHandler Función callback asociada con el evento especificado.
		 */
		public function callService( serviceName:String, endpointName:String, params:Parameter = null, event:Class = null, eventHandler:Function = null ):void
		{
			this.callServiceAndUpload (
				serviceName,
				endpointName,
				params,
				event,
				eventHandler,
				null,
				null
			);
		}

		public function callServiceAndUpload( serviceName:String, endpointName:String, params:Parameter = null, event:Class = null, eventHandler:Function = null, file:FileReference = null, progressProc:Function = null ):void
		{
			var request :Request   = new Request( serviceName );
			
			if ( !params ) {
				params = new Parameter();
			}
			
			request.params = params;
			request.endpointName = endpointName;

			ServiceEventDispatcher.getInstance().addListenerClass( event, eventHandler );
			
			Sender.invokeAndUpload( request, file, progressProc );
		}
		
		/**
		 * Este evento se desencadenará cuando llegue
		 * una respuesta satisfactoria del servidor.
		 */
		public function onResultHandler( response:RequestSuccessEvent ):void
		{
			
		}

		/**
		 * Este evento se desencadenará cuando se
		 * produzca un error en la petición al servidor.
		 */
		public function onFaultHandler( response:RequestFailEvent ):void
		{
			Debug.dump( response.error );
			
			CursorManager.getInstance().removeBusyCursor();
			
			this.alert( "Error en el servidor:\n" + response.error.message );

			return;
		}

		/**
		 * Se desencadenará cuando se produzca un
		 * error no controlado en el servidor.
		 */
		public function unhandledErrorEvent( event:UnhandledErrorEvent ):void
		{
			trace( event.error.message );
			
			CursorManager.getInstance().removeBusyCursor();
			
			this.alert( "Error en el servidor:\n" + event.error.message );
		}

		public function showPopup( popupWindow:Class, parent:UIComponent = null, modal:Boolean = true ):void
		{
			var popupInst:IFlexDisplayObject = PopUpManager.createPopUp( parent, popupWindow, modal );
			
			PopUpManager.centerPopUp( popupInst );
		}
		
		public function alert( message:String, title:String = "", flags:uint = 4, callback:Function = null ):void
		{
			Alert.cancelLabel = "Cancelar";
			Alert.okLabel = "Aceptar";
			Alert.noLabel = "No";
			Alert.yesLabel = "Sí";
			Alert.buttonWidth = 90;
			
			if( !title ) {
				title = appTitle;
			}
			
			Alert.show( message, title, flags, null, callback );
		}
		
		/**
		 * Inicializa la configuración de la aplicación.
		 */
		public function initConfigure():void
		{
			this.configure.contentType   = "application/x-www-form-urlencoded";
			this.configure.encoder       = JROIMContentFactory.ENCODER_BASE64;
			this.configure.onFaultEvent  = this.onFaultHandler;
			this.configure.onResultEvent = this.onResultHandler;
			this.configure.unhandledErrorEvent = this.unhandledErrorEvent;
			this.configure.remoteHost    = this.REMOTE_HOST;

			this.contentFactory.mappings = MappingController.getInstance();
			
			Sender.configure = this.configure;
			Sender.addContentHandler( this.contentFactory, this.configure.contentType);
		}
		
		// Devuelve una instancia única de la clase.
		//
		private static var instance :Globals = null;
		
		public static function getInstance():Globals
		{
			if ( instance == null )
				instance = new Globals();
			
			return( instance );
		}
	}
}